package com.ip.student.common.aspect;

import com.ip.student.common.config.JwtTokenUtil;
import com.ip.user.models.service.SysUserService;
import com.ip.user.models.vo.UserVO;
import com.ip.user.models.service.PermissionService;
import com.ip.user.models.common.annotation.RequiresPermission;
import org.apache.dubbo.config.annotation.DubboReference;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 权限检查切面
 */
@Aspect
@Component
public class PermissionAspect {
    
    @DubboReference
    private PermissionService permissionService;
    
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    
    @DubboReference
    private SysUserService sysUserService;
    
    /**
     * 定义权限检查切点
     * 拦截带有@RequiresPermission注解的方法
     */
    @Pointcut("@annotation(com.ip.user.models.common.annotation.RequiresPermission)")
    public void permissionCheckPointcut() {
    }
    
    /**
     * 权限检查环绕通知
     * @param joinPoint 连接点
     * @param requiresPermission 权限注解
     * @return 方法执行结果
     * @throws Throwable 异常
     */
    @Around("permissionCheckPointcut() && @annotation(requiresPermission)")
    public Object checkPermission(ProceedingJoinPoint joinPoint, 
                                RequiresPermission requiresPermission) throws Throwable {
        // 获取当前请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            throw new RuntimeException("无法获取当前请求上下文");
        }
        
        HttpServletRequest request = attributes.getRequest();
        
        // 从JWT Token中获取用户名
        String authorizationHeader = request.getHeader("Authorization");
        String username = null;
        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            String jwtToken = authorizationHeader.substring(7);
            username = jwtTokenUtil.getUsernameFromToken(jwtToken);
        }
        
        if (username == null) {
            throw new RuntimeException("用户未登录");
        }
        
        // 通过用户名获取用户信息
        UserVO user = sysUserService.getUserByUserName(username);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 获取所需权限编码
        String permissionCode = requiresPermission.value();
        
        // 检查权限
        if (!permissionService.hasPermission(user.getUserId(), permissionCode)) {
            throw new RuntimeException("用户没有权限执行此操作: " + permissionCode);
        }
        
        // 执行原方法
        return joinPoint.proceed();
    }
}